﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Kokomo.Mirror.PeFormat;
using System.Diagnostics;
using Kokomo.Mirror.PeFormat.Symbols;
using System.Reflection;

namespace Kokomo.Mirror.Test
{
	[TestClass]
	public class SymbolTest
	{
		[TestMethod]
		public void TestMethod1()
		{
			string modulePath = typeof(object).Assembly.Location;
			//string modulePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll");
			//string modulePath = Assembly.GetExecutingAssembly().Location;

			//SymbolProvider provider = InternetSymbolStore.Default;
			SymbolProvider provider = new InternetSymbolStore(InternetSymbolStore.InternetSourceStoreUrl);

			SymbolSource source = provider.LoadSymbolsForModule(modulePath);
			Table[] tables = source.Tables.ToArray();

			foreach (var table in tables)
			{
				SymbolTable symbolTable = table as SymbolTable;
				if (symbolTable != null)
				{
					foreach (var symbol in symbolTable)
					{
						switch (symbol.Kind)
						{
							case SymbolKind.Compiland:
								break;
							case SymbolKind.Module:
								break;
							case SymbolKind.PublicSymbol:
								break;
							default:
								break;
						}
					}
				}
				else
				{
					InjectedSourceTable sourceTable = table as InjectedSourceTable;
					if (sourceTable != null)
					{
						foreach (var sourceFile in sourceTable)
						{
							Stream stream = sourceFile.GetStream();
							TextReader reader = new StreamReader(stream);
							string text = reader.ReadToEnd();
						}
					}
				}
			}

			ModuleSymbol globalScope = (ModuleSymbol)source.GlobalScope;
			var children = globalScope.Children.ToArray();

			var sourceFiles = source.GetSourceFiles().ToArray();

			foreach (var sourceFile in sourceFiles)
			{
				InjectedSourceFile injectedSourceFile = source.GetInjectedSourceFile(sourceFile.FileName);
				StreamReader sourceReader = new StreamReader(injectedSourceFile.GetStream());
				string injectedSourceCode = sourceReader.ReadToEnd();

			}


			//CompilandSymbol firstCompiland = globalScope.Compilands.First();
			//SourceFileBase sourceFile = firstCompiland.SourceFile;
			//StreamReader reader = new StreamReader(sourceFile.Stream);
			//string sourceCode = reader.ReadToEnd();

			////string modulePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll");
			//string modulePath = typeof(object).Assembly.Location;
			////string modulePath = Assembly.GetExecutingAssembly().Location;

			//PeModule module = PeModule.Open(modulePath);
			////ExportedFunction export = module.ExportedFunctions[0];

			//using (SymbolHandler handler = new SymbolHandler(Process.GetCurrentProcess().Handle))
			//{
			//    handler.SearchPath = @".;srv*" + SymbolHandler.InternetSymbolStoreUrl;

			//    string symbolFile;
			//    handler.TryGetSymbolFile(modulePath, PeFormat.Symbols.SymbolFileType.PdbFile, out symbolFile);

			//    string debugImageFile;
			//    handler.TryGetSymbolFile(modulePath, PeFormat.Symbols.SymbolFileType.Image, out debugImageFile);

			//    //SymbolModule symModule = handler.LoadModule(modulePath, module.Headers.OptionalHeader.ImageBase);
			//    SymbolModule symModule = handler.LoadModule(symbolFile, module.Headers.OptionalHeader.ImageBase);
			//    //Symbol symbol = symModule.GetSymbol(export.Rva);
			//    var symbols = symModule.EnumerateSymbols();
			//    var sourceFiles = symModule.EnumerateSourceFiles();
			//    var sourceFileTokens = symModule.EnumerateSourceFileTokens();
			//}
		}
	}
}
